﻿#ifndef _VECTORFETURECLASSDBOPERATOR_H_H_
#define _VECTORFETURECLASSDBOPERATOR_H_H_

#include "udatabase/geodb/vectorfeatureclassoperator.h"
//#include "udatabase/interface/ispatialreference.h"
#include "geometry/interface/ienvelope.h"
#include "geometry/interface/igeometry.h"
#include "udatabase/interface/ifields.h"
#include "udatabase/sqldatabase.h"
#include "udatabase/sqlquery.h"
#include "udataset/spatialindex/spatialindex.h"
#include "udatabase/geodb/feature.h"
#include "udatabase/geodb/databasevectorsource.h"

#include <hash_map>

namespace FD{
	namespace Utility{
		namespace DB{
				class CSqlstandardization;
		}
	}
}

namespace FD{
	namespace Utility{
		namespace DB{

//class CDatabaseVectorSource;

class CVectorFeatureClassDBOperator : public CVectorFeatureClassOperator
{
public:
	CVectorFeatureClassDBOperator(CDatabaseVectorSource* pDataSource,const String& dbType);
	virtual ~CVectorFeatureClassDBOperator();
public: 
	virtual FD::Utility::DB::Interface::IDataSource* getDataSourceRef() {return m_pDataSource;}
	///////////////////////////////////////////////////
	virtual bool openDataset(FD::Kernel::DataStream &stream,const String &name);
	virtual bool createDataset(FD::Kernel::DataStream &stream);
	virtual bool deleteDataset(const String &name);

	virtual bool addFeature(/*_in*/ FD::Kernel::DataStream &feature);
	virtual bool addFeatures(vector<String>& fields,
		vector<vector<FD::Kernel::Variant> >& values, bool bigThanGeomMaxLen = false);

	virtual bool getFeature(uint32 id,/*_out*/ FD::Kernel::DataStream &feature);
	virtual bool getFeature(uint32 id,vector<FD::Kernel::Variant>& values,double & lenght,double & area,vector<size_t>& pos);
	virtual bool updateFeature(/*_in*/ FD::Kernel::DataStream &feature);
	virtual bool deleteFeature(uint32 id);
	virtual uint32 getFeatureCount(FD::Kernel::DataStream &filter);
	virtual bool updateExtent();
	virtual bool getExtent(FD::Kernel::Geometry::Interface::IEnvelope *pEnvelope);
	
	virtual bool query(FD::Kernel::DataStream &filter,String &key);
	virtual bool nextFeature(FD::Kernel::DataStream &stream,const String &key);
	virtual bool nextFeature(vector<FD::Kernel::Variant>& values,double & lenght,double & area,vector<size_t>& pos,const String & key);
	virtual bool select(/*_out*/ FD::Kernel::DataStream &os, /*_in*/ FD::Kernel::DataStream &filter);
	virtual bool endQuery(const String &key);
	virtual uint32 queryCount(/*_in*/ FD::Kernel::DataStream &filter);
	

	virtual bool createSpatialIndex(FD::Utility::DB::Interface::ISpatialIndexParam* param);
	virtual bool rebulidSpatialIndex();
	virtual bool deleteSpatialIndex();

	virtual bool addField(const FD::Utility::DB::Interface::IField* field);
	virtual bool deleteField(int32 index);

	virtual FD::Kernel::Variant max(const String &expression);
	virtual FD::Kernel::Variant min(const String &expression);
	virtual FD::Kernel::VariantArray getFieldValues(const String &fieldName,bool isUnique);

	virtual bool Lock();
	virtual bool UnLock();

	virtual String getUpdateTime();
	virtual uint64 getDataVersion();
	virtual bool updateTime() ;
	virtual bool updateDataVersion() ;

	virtual bool setSpatialReference(const FD::Kernel::Math::SpatialReference *sr);
private:
	bool createSpatialIndex2(/*SpatialIndexEnum*/ int32 spaIndex, 
												FD::Kernel::DataStream& stream);
	bool executeMultiSQL(String sql);
	void makeFeatureStream(FD::Utility::DB::CSqlRecord &rec,FD::Kernel::DataStream &stream,vector<bool> *indicator=0);
	void initFeature(FD::Utility::DB::CSqlRecord & rec,vector<FD::Kernel::Variant>& values,double & length,double & area,vector<size_t>& pos,vector<bool>* indicator = 0);

	bool buildSpatialGridIndex(double gridOneSize,
													double gridTwoSize,
													double gridThreeSize);
	bool getGridDefaultSize(double& gridOneSize, double& gridTwoSize, double& gridThreeSize);
private:	
	String							m_strDBType;
	FD::Utility::DB::CSqlstandardization				*sqlStd;
	/* 数据集名字 */
	String		m_Name;
	//数据集表名序列
	String                          m_tableSerialNum;
	// GeometryFieldName
	String							m_ShapeFieldName;
	///* 数据源对象 */
	CDatabaseVectorSource*					m_pDataSource;

	int32						m_fieldCount;
	vector<int32>				m_fieldTypes;
	vector<String>				m_fieldNames;
	//vector<size_t>			m_indexs;
	//CSqlQuery						m_query;
	struct QueryInfo
	{
		FD::Utility::DB::CSqlQuery		   q;
		vector<bool> *indicator;
	};

	OGRE_HashMap<String,QueryInfo>    m_queryDict;
	FD::Kernel::ReadWriteLock mLock;
	uint32 m_SpatialIndexType;
	FD::Utility::SpatialIndex::ISpatialIndex * m_SpatialIndex;
	int32						m_nID;
};


}}} // End of namespaces


#endif //_VECTORFETURECLASSDBOPERATOR_H_H_

